#include "Parser.h"
#include <iostream>

using namespace std;

Parser::Parser() {
    num_of_param = 0;
	Nama = "";
	Jml_Param = 0;
	Jml_Rel = 0;
	for (int i = 0; i < 1000; i++) {
		dummies.push_back(new Facts());
	}
	ite = dummies.begin();
}

Parser::Parser(const Parser&) {}
Parser::~Parser() {}

void Parser::setLine(string s) {
	line = s;
}

string Parser::getLine() {
    return line;
}

string Parser::getName() {
    return fact_name;
}

int Parser::getJumParam(){
	return Jml_Rel;
}

int Parser::getJumRel(){
	return Jml_Param;
}

list<Facts*> * Parser::getFacts() {
	return (&fakta);
}

void Parser::setBeginIte() {
	ite = dummies.begin();
}

bool Parser::isRules(string bla) {
	bool done = false;
	int i = 0;
	while (i < bla.length() && !done) {
		if (bla[i] == ':') {
			done = true;
		} else {
			i++;
		}
	}
	return done;
}

void Parser::ParseInput() {
    int i = 0;
    string _temp;
    while (line[i]!='(') {
        fact_name.push_back(line[i]);
        i++;
    }
	(*ite)->setName(fact_name);
	(*ite)->setIsRule(false);
	fact_name.clear();
    i++;
    while (line[i]!='.') {
        if ((line[i]!=',') && (line[i]!=')') && (line[i]!=' ')) {
            _temp.push_back(line[i]);
            i++;
        } else {
            if (_temp.size() != 0) {
					(*ite)->addParameter(_temp);
					_temp.clear();
					}
            if(line[i] == ',') {(*ite)->addTotalParam();}
            i++;
        }
    }
	fakta.push_back((*ite));
	line.clear();
	ite++;
}

void Parser::Parse(string S) {
	int i;
	i = 0;
	int j = 0;
	string Temp;
	Temp .clear();
	while (S.at(i) != '(') {		// Baca Nama Rule
		Temp.push_back(S.at(i));
		i++;
	}
	(*ite)->setName(Temp);
	(*ite)->setIsRule(true);
	Temp.clear();
	i++;
	Facts* K;
	Rules* R;
	while (i < S.length() && j==0) {
		while (S.at(i) != ')') {
			if ((S.at(i) != ',') && (S.at(i) != ')')){Temp.push_back(S.at(i));}
			i++;
			if ((S.at(i) == ',') || (S.at(i) == ')')) {
				K = *ite;
				R = (Rules*)K;
				R->addParam(Temp);						// Isi parameter Rule
				Temp.clear();			
				Jml_Param++;
			}
			IgnoreBlank(S,&i);
			j = 1;
		}	//	Input kiri
		//ignore ':-'
		i++;
		Temp.clear();
		//selesai ignore ':-'
		IgnoreBlank(S,&i);
		if (S.at(i) == ':') {
			i+=2;
			IgnoreBlank(S,&i);
			}
			Temp.clear();
		while (S.at(i) != '.') {
				if (S.at(i) == ',')  {
					R->addRule(Temp);							//Isi Rule
					Temp.clear();
					Jml_Rel++;
					}
				else if (S.at(i) != '(') {
					Temp.push_back(S.at(i));
					i++;
					while (S.at(i) != ')') {
						Temp.push_back(S.at(i));
						i++;
					}
					Temp.push_back(S.at(i));
					IgnoreBlank(S,&i);
				}
				else{
					Temp.push_back(S.at(i));
					}
			i++;
			if (S.at(i) == '.') {								// Penanganan Rule terakhir
					R->addRule(Temp);
					Temp.clear();
					Jml_Rel++;
					}
			IgnoreBlank(S,&i);
		}
	}
	fakta.push_back((*ite));
	line.clear();
	ite++;
}

void Parser::Print() {
	// cout << "NAMA : " << Nama << endl;
	// list<string>::iterator i;
	// int j,k;
	// j = 1;
	// k = 1;
	// cout << "LIST OF PARAMETER :" << endl;
	// for(i=ListOfParam.begin(); i != ListOfParam.end(); ++i) {
		// cout << "  " << j << " : " << *i << endl;
		// j++;
	// }
	// cout << "NUMBER OF PARAMETER : " << Jml_Param << endl;
	// cout << "LIST OF RELASI :" << endl;
	// for(i=it.begin(); i != fakta.end(); ++i) {
		// cout << "  " << k << " : " << *i << endl;
		// k++;
	// }
	// cout << "NUMBER OF RELASI : " << Jml_Rel << endl;
}

void Parser::IgnoreBlank(string S, int* C) {
	while (S.at(*C) == ' ') {
		(*C)++;
	}
}

void Parser::Clear() {
	Nama = "";
	Jml_Param = 0;
	Jml_Rel = 0;

}

void Parser::searchFR(string s){
	ite = fakta.begin();
	while ((s.compare((*ite)->getName()) != 0) && (ite != fakta.end()))
		{
		ite++;
		}
}

bool IsVariable(string S){
	return (S.at(0) <= 'Z' && S.at(0) >= 'A');
}

string Parser::getFR()
{
	return ((*ite)->getName());
}

string Parser::getNextFR()
{
	ite++;
	return ((*ite)->getName());
}
